#ifndef GRAPHICOBJECTS_H
#define GRAPHICOBJECTS_H

/* Copyright (C) 2011 Riccardo Marson

   This file is part of OpenPool, an open-source game of pool. 

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   RICCARDO MARSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
   AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

  See Readme.rtf for further information.
  
*/

//glew must be included before any other openGL related includes.
#include "Glew/glew.h"

#include "SFML/Config.hpp"
#include "SFML/Graphics.hpp"

#include <math.h>
#include <vector>

#include "interfaces.h"
#include "model_obj.h"
#include "material.h"

// list of classes defined here

class CPointLight;
class CBasicCamera;
class COGLObject;
class COGLSphere;
class COGLPlane;

//holds basic information on one light
class CPointLight : public ILight
{
public:

	CPointLight() {}
	virtual ~CPointLight() {}

	virtual void SetName(string &name);
	virtual void SetAmbientColor(float red, float green , float blue, float alpha);
	virtual void SetDiffuseColor(float red, float green , float blue, float alpha);
	virtual void SetSpecularColor(float red, float green , float blue, float alpha);
	virtual void SetPosition(CVector3 pos);
	virtual string GetName();
	virtual float* GetPosition();
	virtual float* GetAmbientColor();
	virtual float* GetDiffuseColor();
	virtual float* GetSpecularColor();

private:

	string mName;

	float mAmbientColor[4];
    float mDiffuseColor[4];
    float mSpecularColor[4];

    float mPosition[4];
};

//Basic implementation of a Camera object
class CBasicCamera : public ICamera
{
public:

    CBasicCamera();
    virtual ~CBasicCamera();

    virtual void SetName(string &name);
    virtual void SetPosition(CVector3 position);
    virtual void SetLookAt(CVector3 direction);
    virtual void SetUpVector(CVector3 up);
    virtual void Pitch(float angle); //angle in degrees
    virtual void Yaw(float angle); //angle in degrees
    virtual void Roll(float angle); //angle in degrees
    virtual void SetClipDistanceNear(float nearPlane);
    virtual void SetClipDistanceFar(float farPlane);
    virtual string GetName();
    virtual CVector3 GetPosition();
    virtual CVector3 GetLookAt();
    virtual CVector3 GetUpVector();
    virtual float GetClipDistanceNear();
    virtual float GetClipDistanceFar();

protected:

    string mName;
    CVector3 mPosition;
    CVector3 mDirection;
    CVector3 mUp;
    float mClipDistanceNear;
    float mClipDistanceFar;

};

//These classes represent 3d meshes and their properties.
//They can represent both avatars of "real" physics objects or props.

//3D object base class with common variables & interface implementation

//Note: colorMapName and material are used with basicDraw(). 3d model properites override them.
//An object 3d model is drawn by calling GLWidget::drawModel either in its fixed or programmable pipeline version.
class COGLObject : public IOGLObject
{
public:
    COGLObject();
    virtual ~COGLObject();

    virtual eObjectType & Type();
    virtual eObjectID & Id();
    virtual string & Name();
    virtual string & ModelFileName();
    virtual string & ColorMapName();
    virtual CVector3 & Position();
    virtual CVector3 & Heading();
    virtual CVector3 & RotationAxis();
    virtual float & RotationAngle();
    virtual float & Offset();
    virtual void SetModelPtr(const ModelOBJ* modelref);
    virtual const ModelOBJ* ModelPtr();
    virtual bool & HasModel();
    virtual bool & IsVisible();
    virtual CMaterial & Material();

    virtual void BasicDraw() {}

protected:

    eObjectType mType; //object type
    eObjectID mId; // object id
    string mName; //object name
    string mModelFileName; //name of the associated model file without path
    string mColorMapName; //texture name (if any)
    CMaterial mMaterial; //material info
    const ModelOBJ* mModel; //3D .obj model (if any)
    bool mHasModel; //object has a 3d model attached to it.

    bool mIsVisible; // object will be drawn if true

    CVector3 mPosition; //object position
    CVector3 mHeading; //direction where the object is facing
    CVector3 mRotationAxis; //the aribitrary axis of rotation
    float mRotationAngle; //the current rotation angle around mRotationAxis
    float mOffset; //the offset of the model w.r.t the object position
    //(only in the heading direction, needed for positioning and animating the cue)
};

#endif // GRAPHICOBJECTS_H
